Shader "Hidden/VPR/Bloom"
{
    HLSLINCLUDE
    
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    TEXTURE2D(_SourceTex);
    TEXTURE2D(_SourceTexLowMip);
    SamplerState sampler_LinearClamp;
    //纹理中的单像素尺寸  
    float4 _SourceTex_TexelSize;  
    SamplerState sampler_SourceTex;
    SamplerState sampler_SourceTexLowMip;
    
    TEXTURE2D(_Bloom);
    SamplerState sampler_Bloom;
    float _LuminanceThreshold;
    float _Intensity;
    
    float4 _BlurRadius;
    float luminance(float3 color)
    {
        return  0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; 
    }
    struct appdata
    {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
    };
    struct v2f
    {
        
        float4 vertex : SV_POSITION;
        float2 uv : TEXCOORD0;
    };
    struct v2fblurPass
    {
        
        float4 vertex : SV_POSITION;
        float2 uv1 : TEXCOORD0; //存储两个uv坐标
        float2 uv2 : TEXCOORD1; //存储两个uv坐标
        float2 uv3 : TEXCOORD2; //存储两个uv坐标
        float2 uv4 : TEXCOORD3; //存储两个uv坐标
        float2 uv5 : TEXCOORD4;
    };
    struct v2fPass
    {
        
        float4 vertex : SV_POSITION;
        float2 uv0 : TEXCOORD0;
        float2 uv1 : TEXCOORD1;
    };
    v2f vert_Bloom(appdata v)
    {
        v2f o;
        o.vertex = TransformObjectToHClip(v.vertex.xyz);
        o.uv=v.uv;
        return o;
    }
    v2f vert_BloomUpsample(appdata v)
    {
        v2f o;
        o.vertex = TransformObjectToHClip(v.vertex.xyz);
        o.uv=v.uv;
        return o;
    }
    // 片元着色器
    float4 fragExtractBright(v2f i) : SV_Target
    {
        
        float texelSize = _SourceTex_TexelSize.x;
        float2 uv=i.uv;
        half4 A = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, -1.0));
        half4 B = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, -1.0));
        half4 C = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, -1.0));
        half4 D = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, -0.5));
        half4 E = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, -0.5));
        half4 F = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 0.0));
        half4 G = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
        half4 H = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 0.0));
        half4 I = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, 0.5));
        half4 J = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, 0.5));
        half4 K = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 1.0));
        half4 L = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, 1.0));
        half4 M = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 1.0));

        half2 div = (1.0 / 4.0) * half2(0.5, 0.125);

        half4 o = (D + E + I + J) * div.x;
        o += (A + B + G + F) * div.y;
        o += (B + C + H + G) * div.y;
        o += (F + G + L + K) * div.y;
        o += (G + H + M + L) * div.y;
        // clamp 约束到 0 - 1 区间
        float3 color =o;
        float val = clamp(luminance(color) - _LuminanceThreshold, 0.0, 1.0);

        return float4(color * val,1);
    }

    float4 fragUpSample(v2f i) : SV_Target
    {
        float4 color =float4(0,0,0,1);
        //float2 halfPixel = 0.5f * _SourceTex_TexelSize.zw;
        //_SourceTex_TexelSize
        float3 c = _SourceTex.Sample(sampler_SourceTex, i.uv).rgb;
        float3 Lowc = _SourceTexLowMip.Sample(sampler_SourceTexLowMip, i.uv).rgb;
        color.rgb=lerp(c,Lowc,0.5);
        
        

        return color ;
    }
    ENDHLSL
    SubShader
    {
       
        Cull Off ZWrite Off ZTest Always
        Pass
        {
            Name "Bloom Luminance"
            HLSLPROGRAM
            #pragma vertex vert_Bloom
            #pragma fragment fragExtractBright
            
            ENDHLSL
        }
        
        Pass
        {
            Name "Blur Horizontal"
            HLSLPROGRAM
            #pragma vertex vert_HorizontalBlur
            #pragma fragment frag_HorizontalBlur
            v2fblurPass vert_HorizontalBlur(appdata v)
            {
                v2fblurPass o;
                _BlurRadius *= _SourceTex_TexelSize.xyxy;
                o.vertex = TransformObjectToHClip(v.vertex.xyz);
                o.uv1=v.uv + _BlurRadius.xy * half2(1,0) * -2.0;
                o.uv2=v.uv + _BlurRadius.xy * half2(1,0) * -1.0;
                o.uv3=v.uv ;
                o.uv4=v.uv+ _BlurRadius.xy * half2(1,0) * 1.0;
                o.uv5=v.uv+ _BlurRadius.xy * half2(2,0) * 2.0;
        
                return o;
            }
            half4 frag_HorizontalBlur (v2fblurPass i) : SV_Target
            {
                half4 s = 0;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv1)* 0.05;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv2)* 0.25;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv3)* 0.40;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv4)* 0.25;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv5)* 0.05;
                
                return s;
            }
            ENDHLSL
        }
        Pass
        {
            Name "Blur Vorizontal"
            HLSLPROGRAM
            #pragma vertex vert_VorizontalBlur
            #pragma fragment frag_VorizontalBlur
            v2fblurPass vert_VorizontalBlur(appdata v)
            {
                v2fblurPass o;
                _BlurRadius *= _SourceTex_TexelSize.xyxy;  
                o.vertex = TransformObjectToHClip(v.vertex.xyz);
                o.uv1=v.uv + _BlurRadius.zw * half2(0,1) * -2.0;
                o.uv2=v.uv + _BlurRadius.zw * half2(0,1) * -1.0;
                o.uv3=v.uv ;
                o.uv4=v.uv+ _BlurRadius.zw * half2(0,1) * 1.0;
                o.uv5=v.uv+ _BlurRadius.zw * half2(0,1) * 2.0;
        
                return o;
            }
            half4 frag_VorizontalBlur (v2fblurPass i) : SV_Target
            {
                half4 s = 0;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv1)* 0.05;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv2)* 0.25;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv3)* 0.40;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv4)* 0.25;
                s += _SourceTex.Sample(sampler_SourceTex, i.uv5)* 0.05;
                
                return s;
            }
            ENDHLSL
        }
        Pass
        {
            Name "Bloom Upsample"
            HLSLPROGRAM
            #pragma vertex vert_BloomUpsample
            #pragma fragment fragUpSample
            ENDHLSL
        }
        //混合原图像，高亮区域高斯模糊的后的结果
        Pass
        {
            Name "Bloom Blend"
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            v2fPass vert(appdata input)
            {
                v2fPass output;
                output.vertex = TransformObjectToHClip(input.vertex);
                output.uv0 = input.uv;
                
                #if UNITY_UV_STARTS_AT_TOP
                if(_SourceTex_TexelSize.y<0.0)
                    output.uv1 = input.uv;
                #endif
                return output;
            }

            float4 frag (v2fPass input) : SV_Target
            {
                half3 tex = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, input.uv0);
                half3 bloom = SAMPLE_TEXTURE2D(_Bloom, sampler_Bloom, input.uv1);
                
                return float4(tex+bloom*_Intensity,1.0f);
            }
            ENDHLSL
        }
     
    }
}